/**
 * @file port_ble_gap.c
 * @brief 
 * @author dotc (dotchan@qq.com)
 * @date 2025-01-21
 * 
 * @copyright Copyright (c) 2025 by 深圳市鹏天微智能科技有限公司, All Rights Reserved.
 */

#if defined(CONFIG_PORT_BLE_ENABLE)

/* ==================== [Includes] ========================================== */

// 单独控制本文件功能的优先级
#define XF_LOG_LEVEL            CONFIG_PORT_BLE_GAP_LOG_LEVEL

#include "xf_ble_gap.h"
#include "xf_utils.h"
#include "xf_init.h"
#include "xf_task.h"
#include "xf_ble_port_utils.h"
#include "port_ble_common.h"

#include "bledef.h"
#include "drvs.h"
#include "prf_api.h"
#include "blelib.h"

/* ==================== [Defines] =========================================== */

#define TAG "port_ble_gap"


#define DEFAULT_PORT_BLE_PHY            (GAP_PHY_LE_1MBPS)
#define DEFAULT_PORT_BLE_MTU_SIZE       (512)
#define DEFAULT_PORT_BLE_ROLE           (GAP_ROLE_NONE)
#define DEFAULT_PORT_BLE_PAIR_MODE      (GAPM_PAIRING_LEGACY)
#define DEFAULT_PORT_BLE_DEV_CFG        (CFG_FLAG_NONE | CFG_FLAG_PUBLIC_ADDR_BIT)

#define PORT_BLE_GAP_ADV_DATA_MAX_LEN   (31)


#define DEFAULT_PORT_PAIR_RESP_IOCAP_FLAG           GAP_IO_CAP_NO_INPUT_NO_OUTPUT
#define DEFAULT_PORT_PAIR_RESP_OOB_FLAG             GAP_OOB_AUTH_DATA_NOT_PRESENT
#define DEFAULT_PORT_PAIR_RESP_AUTHRN_RQMT_FLAG     GAP_AUTH_REQ_NO_MITM_NO_BOND
#define DEFAULT_PORT_PAIR_RESP_SECURITY_RQMT_FLAG               GAP_NO_SEC
#define DEFAULT_PORT_PAIR_RESP_INITIATOR_KEY_DISTRIBUTION_FLAG  GAP_KDIST_NONE
#define DEFAULT_PORT_PAIR_RESP_RESPONDER_KEY_DISTRIBUTION_FLAG  GAP_KDIST_ENCKEY
#define DEFAULT_PORT_PAIR_ENC_KEY_SIZE_FLAG                     GAP_KEY_LEN

#define PORT_BLE_NAME_MAX_LEN   (20)        // DEV_NAME_MAX_LEN

#define DEFAULT_PORT_DEFAULT_CONN_PARAM_TYPE        GAPM_INIT_TYPE_DIRECT_CONN_EST
#define DEFAULT_PORT_DEFAULT_CONN_PARAM_PROP_PHY    GAPM_INIT_PROP_1M_BIT
#define DEFAULT_PORT_DEFAULT_CONN_PARAM_TIMEOUT     100 // timeout unit in 10ms          

#define PORT_INVALID_SCAN_ID    (UINT8_MAX)

/* ==================== [Typedefs] ========================================== */

struct app_env_tag
{
    // Application State
    state_t state;

    // Curr Connection Index
    uint8_t curidx;

    #if (BLE_MULTI_CONN)
    // Bits of Connection Index(0:Not Connect, 1:Connected)
    uint8_t conbits;
    // Bits of Connection Roles(0:Master or None, 1:Slave)
    uint8_t conrole;
    #endif //(BLE_MULTI_CONN)
};

typedef struct _port_ble_name_t
{
    uint8_t name[PORT_BLE_NAME_MAX_LEN];
    uint8_t len;
} port_ble_name_t;

/**
 * @brief gapm_scan_param 的同构体
 * 
 */
typedef struct _port_gapm_scan_param_t
{
    /// Type of scanning to be started (@see enum gapm_scan_type)
    uint8_t type;
    /// Properties for the scan procedure (@see enum gapm_scan_prop for bit signification)
    union
    {
        struct
        {
            uint8_t prop_type_and_phy   :4;
            uint8_t prop_filter         :4;
        };
        uint8_t prop_all_u8;
    };
    
    /// Duplicate packet filtering policy
    uint8_t dup_filt_pol;
    /// Reserved for future use
    uint8_t rsvd;
    /// Scan window opening parameters for LE 1M PHY
    struct gapm_scan_wd_op_param scan_param_1m;
    /// Scan window opening parameters for LE Coded PHY
    struct gapm_scan_wd_op_param scan_param_coded;
    /// Scan duration (in unit of 10ms). 0 means that the controller will scan continuously until
    /// reception of a stop command from the application
    uint16_t duration;
    /// Scan period (in unit of 1.28s). Time interval betweem two consequent starts of a scan duration
    /// by the controller. 0 means that the scan procedure is not periodic
    uint16_t period;
} port_gapm_scan_param_t;

/* ==================== [Static Prototypes] ================================= */

xf_err_t _default_ble_gap_evt_cb(
    xf_ble_gap_evt_t event,
    xf_ble_gap_evt_cb_param_t *param);

/* ==================== [Static Variables] ================================== */

static xf_ble_gap_evt_cb_t s_ble_gap_evt_cb = _default_ble_gap_evt_cb;

static struct gapm_dev_config s_ble_dev_cfg =
{
    .pref_phy = DEFAULT_PORT_BLE_PHY,
    .gap_role = DEFAULT_PORT_BLE_ROLE,
    .pairing = DEFAULT_PORT_BLE_PAIR_MODE,
    .max_mtu = DEFAULT_PORT_BLE_MTU_SIZE,
    .dev_cfg = DEFAULT_PORT_BLE_DEV_CFG,
};

static bd_addr_t s_ble_addr = {0xCC, 0x32, 0x20, 0x20, 0x32, 0xDD};

static port_ble_name_t s_ble_name = {
    .name = "XF_BLE",
    .len = sizeof("XF_BLE"),
};

static xf_ble_appearance_t s_ble_appearance = XF_BLE_APPEARANCE_UNKNOWN;

static enum gap_sec_req const s_map_security_rqmt_to_gap_sec_req[] = 
{
    [XF_BLE_SM_SECURITY_M1L1_NONE]                      = GAP_NO_SEC,                    
    [XF_BLE_SM_SECURITY_M1L2_UNAUTHEN_ENCRYPT_PAIR]     = GAP_SEC1_NOAUTH_PAIR_ENC,      
    [XF_BLE_SM_SECURITY_M1L3_AUTHEN_ENCRYPT_PAIR]       = GAP_SEC1_AUTH_PAIR_ENC,         
    [XF_BLE_SM_SECURITY_M1L4_SECURE_CONN_ENCRYPT_PAIR]  = GAP_SEC1_SEC_CON_PAIR_ENC,       
            
    [XF_BLE_SM_SECURITY_M2L1_UNAUTHEN_DATA_SIGN_PAIR]   = GAP_SEC2_NOAUTH_DATA_SGN,
    [XF_BLE_SM_SECURITY_M2L2_AUTHEN_DATA_SIGN_PAIR]     = GAP_SEC2_AUTH_DATA_SGN,   
};

static uint8_t s_scan_id = PORT_INVALID_SCAN_ID;

typedef struct _port_ble_link_info_t
{
    uint8_t conn_id;
    xf_ble_addr_t addr;
} port_ble_link_info_t;

static port_ble_link_info_t *(s_list_port_ble_link[DEFAULT_BLE_APP_MAX_CNT]) = {NULL};


const struct gapm_conn_param port_ble_default_conn_param = 
{
    /// Minimum value for the connection interval (in unit of 1.25ms). Allowed range is 7.5ms to 4s.
    .conn_intv_min = 10,
    /// Maximum value for the connection interval (in unit of 1.25ms). Allowed range is 7.5ms to 4s.
    .conn_intv_max = 10,
    /// Slave latency. Number of events that can be missed by a connected slave device
    .conn_latency = 0,
    /// Link supervision timeout (in unit of 10ms). Allowed range is 100ms to 32s
    .supervision_to = 300,
    /// Recommended minimum duration of connection events (in unit of 625us)
    .ce_len_min = 2,
    /// Recommended maximum duration of connection events (in unit of 625us)
    .ce_len_max = 4,
};

/* ==================== [Macros] ============================================ */

/* ==================== [Global Functions] ================================== */

struct gapm_dev_config *port_ble_dev_cfg_record_get(void)
{
    return &s_ble_dev_cfg;
}

void port_ble_dev_cfg_record_set(struct gapm_dev_config *dev_cfg)
{
    XF_ASSERT(dev_cfg != NULL, XF_RETURN_VOID, TAG, "dev_cfg == NULL");
    s_ble_dev_cfg = *dev_cfg;
}

bd_addr_t *port_ble_get_local_addr(void)
{
    return &s_ble_addr;
}
/**
 * @brief BLE 功能开启
 *
 * @note 包含所有 BLE 开启前的处理
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_enable(void)
{
    rcc_ble_en();
    rcc_adc_en();

#if (BLE_LITELIB)
    if (RSN_IS_BLE_WKUP(rsn))
    {
        // Resume BLE (Only supported in LiteLib)
        ble_resume();
        rc32k_conf(RCLK_DPLL, 7);
    }
    else
#endif //(BLE_LITELIB)
    {
        heap_cfg_t heap;
        
        // Config Heap, resized with special lib
        heap.base[MEM_ENV] = BLE_HEAP_BASE;
        heap.size[MEM_ENV] = BLE_HEAP_ENV_SIZE;
        heap.base[MEM_MSG] = BLE_HEAP_BASE + BLE_HEAP_ENV_SIZE;
        heap.size[MEM_MSG] = BLE_HEAP_MSG_SIZE;
        ble_heap(&heap);

        // Init BLE and App
        ble_init();
        ble_app();

        // Init RC32K with Calibration
        #if (CFG_SLEEP || RC32K_CALIB_PERIOD)
        //rc32k_init(); - replace to watch calib result
        rc32k_conf(RCLK_DPLL, 7);
//        rc32k_conf(RCLK_HSE, 0x1F);

        uint16_t trim = rc32k_calib();
        DEBUG("RC32K Calib(Msb:%d,Lsb:%d)", trim & 0xF, trim >> 4);

        #endif //(CFG_SLEEP || RC32K_CALIB_PERIOD)
    }

    // Init RF & Modem
    rfmdm_init();
    
    NVIC_EnableIRQ(BLE_IRQn);

    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_SRC_BLE_APP, 10);
    
    gapm_set_dev(&s_ble_dev_cfg, &s_ble_addr, NULL);
    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_SRC_GAPM_SET_DEV_CONFIG, 10);

    return XF_OK;
}

/**
 * @brief BLE 功能关闭
 *
 * @note 包含所有 BLE 关闭前的处理
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_disable(void)
{

    return XF_ERR_NOT_SUPPORTED;
}

/**
 * @brief BLE GAP 设置本端设备地址
 *
 * @param addr BLE 地址信息，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - XF_ERR_NOT_SUPPORTED  不支持
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_set_local_addr(xf_ble_addr_t *addr)
{
    struct gapm_dev_config cfg_copy = *port_ble_dev_cfg_record_get();
    
    if(addr->type == XF_BLE_ADDR_TYPE_PUBLIC_DEV)
    {
        cfg_copy.dev_cfg |= CFG_FLAG_PUBLIC_ADDR_BIT; 
    }
    else
    {
        cfg_copy.dev_cfg &= (~CFG_FLAG_PUBLIC_ADDR_BIT); 
    }

    bd_addr_t * local_addr = port_ble_get_local_addr();
    memcpy(local_addr->addr, (const void *)addr->addr, XF_BLE_ADDR_LEN);

    gapm_set_dev(&cfg_copy, local_addr, NULL);
    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_SET_LOCAL_ADDR, 10);

    port_ble_dev_cfg_record_set(&cfg_copy);
    return XF_OK;
}

/**
 * @brief BLE GAP 获取本端设备地址
 *
 * @param[out] addr BLE 地址信息，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_get_local_addr(xf_ble_addr_t *addr)
{
    struct gapm_dev_config *dev_cfg = port_ble_dev_cfg_record_get();
    bd_addr_t *local_addr = port_ble_get_local_addr();

    /* FIXME 这里貌似只有 公共与随机的类型  */
    addr->type = (dev_cfg->dev_cfg & CFG_FLAG_PUBLIC_ADDR_BIT !=0)? XF_BLE_ADDR_TYPE_PUBLIC_DEV:XF_BLE_ADDR_TYPE_RANDOM_DEV;

    memcpy(addr->addr, (const void *)local_addr->addr, XF_BLE_ADDR_LEN);
    return XF_OK;
}

/**
 * @brief BLE GAP 设置本端设备的外观
 *
 * @param appearance 外观值，见 @ref xf_ble_appearance_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_set_local_appearance(xf_ble_appearance_t appearance)
{
    s_ble_appearance = appearance;
    return XF_OK;
}

/**
 * @brief BLE GAP 获取本端设备的外观
 *
 * @param[out] appearance 外观值，见 @ref xf_ble_appearance_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_get_local_appearance(xf_ble_appearance_t *appearance)
{
    *appearance = s_ble_appearance;
    return XF_OK;
}

/**
 * @brief BLE GAP 设置本端设备名称
 *
 * @param name 设备名
 * @param len 设备名长度
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_set_local_name(const uint8_t *name, const uint8_t len)
{
    if(len >= PORT_BLE_NAME_MAX_LEN)
    {
        return XF_ERR_INVALID_ARG;
    }
    xf_memcpy(s_ble_name.name, name, len);
    s_ble_name.len = len;
    return XF_OK;
}

/**
 * @brief BLE GAP 获取本端设备名称
 *
 * @param[out] name 设备名
 * @param len 设备名长度
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_get_local_name(uint8_t *name, uint8_t *len)
{
    xf_memcpy(name, s_ble_name.name, s_ble_name.len);
    *len = s_ble_name.len;
    return XF_OK;
}

static const uint16_t s_map_xf_gap_adv_type_to_adv_prop[] = 
{
    [XF_BLE_GAP_ADV_TYPE_CONN_SCAN_UNDIR] = GAPM_ADV_PROP_UNDIR_CONN_MASK,
    [XF_BLE_GAP_ADV_TYPE_CONN_NONSCAN_DIR] = GAPM_ADV_PROP_DIR_CONN_HDC_MASK,
    [XF_BLE_GAP_ADV_TYPE_NONCONN_SCAN_UNDIR] = GAPM_ADV_PROP_NON_CONN_SCAN_MASK,
    [XF_BLE_GAP_ADV_TYPE_NONCONN_NONSCAN_UNDIR] = GAPM_ADV_PROP_NON_CONN_NON_SCAN_MASK,
    [XF_BLE_GAP_ADV_TYPE_CONN_NONSCAN_DIR_LOW_DUTY] = GAPM_ADV_PROP_DIR_CONN_LDC_MASK,
};

static uint8_t const s_map_xf_gap_addr_type_to_adv_own_addr_type[] =
{
    [XF_BLE_ADDR_TYPE_PUBLIC_DEV] = GAPM_STATIC_ADDR,
    [XF_BLE_ADDR_TYPE_RANDOM_DEV] = GAPM_STATIC_ADDR,
    [XF_BLE_ADDR_TYPE_RPA_PUBLIC] = GAPM_GEN_NON_RSLV_ADDR,
    [XF_BLE_ADDR_TYPE_RPA_RANDOM] = GAPM_GEN_RSLV_ADDR,
};

static inline xf_err_t _port_ble_gap_set_adv_data(uint8_t adv_id, const xf_ble_gap_adv_data_t *data)
{
    uint8_t data_packed_size = 0;
    uint8_t data_packed_size_temp = 0;

    /* 解析 adv_struct_set ，设置广播数据 (adv_data) */
    data_packed_size = xf_ble_gap_adv_data_packed_size_get(data->adv_struct_set);
    XF_LOGD(TAG, "data_packed_size (adv_data):%d", data_packed_size);
    data_packed_size_temp = data_packed_size == 0?1:data_packed_size;   // 避免 无广播数据时数组长度为 0
    uint8_t data_packed_adv[data_packed_size_temp];
    /* 有广播数据 -> 解析广播数据单元集合，填充广播数据包 */
    if(data_packed_size > 0)
    {
        // memset(data_packed_adv, 0, data_packed_size);
        xf_ble_gap_adv_data_packed_by_adv_struct_set(data_packed_adv, data->adv_struct_set);

        gapm_set_adv_data(adv_id, GAPM_SET_ADV_DATA, data_packed_size, data_packed_adv);
        port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_GAP_ADV_DATA_SET, 10);
    }

    /* 解析 scan_rsp_struct_set ，设置扫描响应数据 (scan_rsp_data) */
    data_packed_size = xf_ble_gap_adv_data_packed_size_get(data->scan_rsp_struct_set);
    XF_LOGD(TAG, "data_packed_size (scan_rsp_data):%d", data_packed_size);
    data_packed_size_temp = data_packed_size == 0?1:data_packed_size;   // 避免 无扫描响应数据时数组长度为 0
    uint8_t data_packed_scan_rsp[data_packed_size_temp];
    /* 有扫描响应数据 -> 解析扫描响应数据单元集合，填充扫描响应数据包 */
    if(data_packed_size > 0)
    {
        // memset(data_packed_scan_rsp, 0, data_packed_size);
        xf_ble_gap_adv_data_packed_by_adv_struct_set(data_packed_scan_rsp, data->scan_rsp_struct_set);

        gapm_set_adv_data(adv_id, GAPM_SET_SCAN_RSP_DATA, data_packed_size, data_packed_scan_rsp);
        port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_GAP_SCAN_RSP_DATA_SET, 10);
    }
    return XF_OK;
}

/**
 * @brief BLE GAP 广播创建
 *
 * @param adv_id 广播 ID
 * @param param 广播参数，见 @ref xf_ble_gap_adv_param_t
 * @param data 广播数据，见 @ref xf_ble_gap_adv_data_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_create_adv(uint8_t *adv_id,
    const xf_ble_gap_adv_param_t *param,
    const xf_ble_gap_adv_data_t *data
)
{
    struct gapm_adv_create_param adv_param = {0};

    // Advertising type (@see enum gapm_adv_type)
    adv_param.type                  = GAPM_ADV_TYPE_LEGACY;
    // Discovery mode (@see enum gapm_adv_disc_mode)
    adv_param.disc_mode             = GAPM_ADV_MODE_GEN_DISC;   //  dotc: 这个貌似跟广播数据的 flags 一样 
    // Advertising properties (@see enum gapm_adv_prop)
    #if (DBG_GAPM)
    adv_param.prop                  = GAPM_ADV_PROP_UNDIR_CONN_MASK | GAPM_ADV_PROP_SCAN_REQ_NTF_EN_BIT;
    #else
    adv_param.prop                  = s_map_xf_gap_adv_type_to_adv_prop[param->type]; //param->type;          //  dotc: 这个标准中是 Advertising_Type
    #endif
    // Filtering policy (@see enum gapm_adv_filter_policy)
    adv_param.filter_pol            = param->filter_policy;
    // Config primary advertising (@see gapm_adv_prim_cfg)
    adv_param.prim_cfg.phy          = GAP_PHY_LE_1MBPS;         //  dotc: 传统广播（legacy）只支持 1M PHY 
    adv_param.prim_cfg.chnl_map     = param->channel_map;
    adv_param.prim_cfg.adv_intv_min = param->min_interval;
    adv_param.prim_cfg.adv_intv_max = param->max_interval;
    
    msg_info_list_index_t index_get = MSG_INFO_LIST_INDEX_INVALID;
    port_msg_param_var_t *param_get = NULL;

    gapm_create_advertising(
        s_map_xf_gap_addr_type_to_adv_own_addr_type[param->own_addr.type], &adv_param);
    port_msg_evt_get_with_check(index_get, PORT_MSG_EVT_BLE_GAP_ADV_CREATE, &param_get, 10);
    port_msg_evt_clear_with_assert(index_get);

    uint8_t _adv_id = param_get->gapm_activity_created_ind.actv_idx;
    if(adv_id != NULL)
    {
        *adv_id = _adv_id;
    }

    /* 设置广播数据 (广播包以及扫描响应包) */
    xf_err_t ret = _port_ble_gap_set_adv_data(_adv_id, data);
    XF_CHECK(ret != XF_OK, ret, TAG, "set adv data failed:%d", ret);

    return XF_OK;
}

/**
 * @brief BLE GAP 广播销毁
 *
 * @param adv_id 广播 ID
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_delete_adv(uint8_t adv_id)
{
    gapm_delete_advertising(adv_id);
    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_GAP_ADV_DEL, 10);
    return XF_OK;
}

/**
 * @brief BLE GAP 广播开启
 *
 * @param adv_id 广播 ID
 * @param duration 广告时长，0 表示始终开启
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_start_adv(uint8_t adv_id, uint16_t duration)
{
    gapm_start_advertising(adv_id, duration);
    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_GAP_ADV_START, 10);
    return XF_OK;
}

/**
 * @brief BLE GAP 广播关闭
 *
 * @param adv_id 广播 ID
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_stop_adv(uint8_t adv_id)
{
    gapm_stop_advertising(adv_id);
    port_msg_evt_get_with_check_and_clear(PORT_MSG_EVT_BLE_GAP_ADV_STOP, 10);
    return XF_OK;
}

/**
 * @brief BLE GAP 设置广播数据
 *
 * @param adv_id 广播 ID，活跃中的广播的 ID
 * @param data 广播数据，见 @ref xf_ble_gap_adv_data_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_set_adv_data(
    uint8_t adv_id, const xf_ble_gap_adv_data_t *data)
{
    /* 设置广播数据 (广播包以及扫描响应包) */
    xf_err_t ret = _port_ble_gap_set_adv_data(adv_id, data);
    XF_CHECK(ret != XF_OK, ret, TAG, "set adv data failed:%d", ret);
    return XF_OK;
}

/**
 * @brief BLE GAP 扫描开启
 *
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_start_scan(const xf_ble_gap_scan_param_t *param)
{
    if(s_scan_id != PORT_INVALID_SCAN_ID)
    {
        return XF_ERR_BUSY;
    }

    /* 目前 RF 原因，不支持 PHY_CODED */
    XF_ASSERT(param->phy != XF_BLE_GAP_SCAN_PHY_CODED, XF_ERR_INVALID_ARG,
        TAG, "PHY_CODED is not support!");

    /* 创建扫描活动 */
    msg_info_list_index_t index_get = MSG_INFO_LIST_INDEX_INVALID;
    port_msg_param_var_t *param_get = NULL;
    gapm_create_activity(GAPM_ACTV_TYPE_SCAN, GAPM_STATIC_ADDR);
    port_msg_evt_get_with_check(index_get, PORT_MSG_EVT_SRC_GAM_SCAN_CREATE, &param_get, 10);
    s_scan_id = param_get->gapm_activity_created_ind.actv_idx;
    port_msg_evt_clear_with_assert(index_get);

    // [0,1] -> [0,2]
    uint8_t shift_scan_type = (param->type ^ 0x0) + param->type;
    // [1,4] -> [0x01,0x10]([1,2])
    uint8_t phy_type = (param->phy >> 2) + 1;

    port_gapm_scan_param_t scan_param = {
        /// Type of scanning to be started (@see enum gapm_scan_type)
        .type = GAPM_SCAN_TYPE_CONN_DISC, //  FIXME 参数为标准中没出现的，暂时设置为 可连接的发现
        /* SDK 侧该参数的配置不管什么扫描类型均需设置 [1:0]，主动扫描时还需一样的配置[3:2]  */
        .prop_type_and_phy = (phy_type << shift_scan_type) | phy_type,
        .prop_filter = param->filter_policy,
        .scan_param_1m = {
            .scan_intv = param->interval,
            .scan_wd = param->window,
        },
        .scan_param_coded = {
            .scan_intv = param->interval,
            .scan_wd = param->window,
        },
        .dup_filt_pol = 0,  // xf 侧目前没有重复包过滤参数
        .duration = 0,      // 0 为一直扫描 FIXME 参数为标准中没出现的
        .period = 0,        // 0 为非周期性扫描 FIXME 参数为标准中没出现的
    };
    
    /* 启动服务 */
    XF_LOGD(TAG,"s_scan_id:%d", s_scan_id);
    gapm_start_activity(s_scan_id, sizeof(port_gapm_scan_param_t), &scan_param);
    /* FIXME 此处触发的事件紧有 GAPM_CMP_EVT，OP: GAPM_START_ACTIVITY ，无法辨别是那个活动的 */
    port_msg_evt_get_with_check(index_get, PORT_MSG_EVT_BLE_GAP_SCAN_START, &param_get, 10);
    port_msg_evt_clear_with_assert(index_get);
    return XF_OK;
}

/**
 * @brief BLE GAP 扫描停止
 *
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_stop_scan(void)
{
    /* 先缓存 s_scan_id 值并修改为无效值，避免期间一直触发收到扫描结果的事件 */
    uint8_t scan_id = s_scan_id;
    s_scan_id = PORT_INVALID_SCAN_ID;

    msg_info_list_index_t index_get = MSG_INFO_LIST_INDEX_INVALID;
    port_msg_param_var_t *param_get = NULL;
    gapm_stop_activity(scan_id);
    port_msg_evt_get_with_check_goto(index_get, PORT_MSG_EVT_BLE_GAP_SCAN_STOP, &param_get, 10, _TAG_ERR);

    gapm_delete_activity(scan_id);
    port_msg_evt_get_with_check_goto(index_get, PORT_MSG_EVT_SRC_GAP_SCAN_DEL, &param_get, 10, _TAG_ERR);
    port_msg_evt_clear_with_assert_goto(index_get, _TAG_ERR);

    XF_LOGD(TAG, "DEL SCAN id:%d",
        param_get->gapm_activity_delete_cmd.actv_idx);
    if(param_get->gapm_activity_delete_cmd.actv_idx != scan_id)
    {
        s_scan_id = scan_id;    // 恢复为缓存的 scan_id
        return XF_ERR_INVALID_CHECK;
    }
    return XF_OK;

_TAG_ERR:;
    s_scan_id = scan_id;    // 恢复为缓存的 scan_id
    return XF_ERR_INVALID_CHECK;
}

/**
 * @brief BLE GAP 更新连接参数
 *
 * @param conn_id 连接 (链接) ID
 * @param params 更新连接参数的信息，见 @ref xf_ble_gap_conn_param_update_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_update_conn_params(
    uint16_t conn_id, xf_ble_gap_conn_param_update_t *params)
{
    struct gapc_conn_param conn_param = 
    {
        .intv_min = params->min_interval,
        .intv_max = params->max_interval,
        .latency = params->latency,
        .time_out = params->timeout,
    };

    gapc_update_param(conn_id, &conn_param);

    /* 此处不再等待时间，而是直接返回，事件交由 xf 层应用进行处理 */
    return XF_OK;
}

port_ble_link_info_t *port_ble_link_alloc(void)
{
    uint8_t index = 0;
    for(; index < DEFAULT_BLE_APP_MAX_CNT; index++)
    {
        if(s_list_port_ble_link[index] == NULL)
        {
            s_list_port_ble_link[index] = xf_malloc(sizeof(port_ble_link_info_t));
            if(s_list_port_ble_link[index] == NULL)
            {
                return NULL;
            }
            xf_memset(s_list_port_ble_link[index], 0, sizeof(port_ble_link_info_t));
            return s_list_port_ble_link[index];
        }
    }
    return NULL;
}

xf_err_t port_ble_link_free(port_ble_link_info_t *link)
{
    uint8_t index = 0;
    for(; index < DEFAULT_BLE_APP_MAX_CNT; index++)
    {
        if(s_list_port_ble_link[index] == link)
        {
            xf_free(link);
            s_list_port_ble_link[index] = NULL;
            return XF_OK;
        }
    }
    return XF_ERR_INVALID_ARG;
}

port_ble_link_info_t *port_ble_link_get_by_addr(const xf_ble_addr_t *addr)
{
    uint8_t index = 0;
    for(; index < DEFAULT_BLE_APP_MAX_CNT; index++)
    {
        if( (s_list_port_ble_link[index] != NULL)
        &&  (xf_memcmp(&s_list_port_ble_link[index]->addr,
                addr, sizeof(xf_ble_addr_t)) == 0)
        )
        {
            return s_list_port_ble_link[index];
        }
    }
    return NULL;
}

/**
 * @brief BLE GAP 发起连接
 *
 * @param addr 要连接的地址，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_connect(const xf_ble_addr_t *addr)
{
    port_ble_link_info_t *link = port_ble_link_alloc();
    XF_CHECK(link == NULL, XF_ERR_RESOURCE, TAG, "port_ble_link_alloc failed!");

    msg_info_list_index_t index_get = MSG_INFO_LIST_INDEX_INVALID;
    port_msg_param_var_t *param_get = NULL;

    gapm_create_activity(GAPM_ACTV_TYPE_INIT, GAPM_STATIC_ADDR);
    port_msg_evt_get_with_check(index_get, PORT_MSG_EVT_SRC_GAM_INIT_CREATE, &param_get, 10);
    link->conn_id = param_get->gapm_activity_created_ind.actv_idx;
    port_msg_evt_clear_with_assert(index_get);

    struct gapm_init_param init_param =
    {
        .type = DEFAULT_PORT_DEFAULT_CONN_PARAM_TYPE,
        .prop = DEFAULT_PORT_DEFAULT_CONN_PARAM_PROP_PHY,
        .conn_to = DEFAULT_PORT_DEFAULT_CONN_PARAM_TIMEOUT,
        .scan_param_1m.scan_intv = GAP_SCAN_FAST_INTV,
        .scan_param_1m.scan_wd = GAP_SCAN_FAST_WIND,
        .conn_param_1m = port_ble_default_conn_param,
        .peer_addr.addr_type = addr->type,
    };
    
    memcpy(&init_param.peer_addr.addr, addr->addr, XF_BLE_ADDR_LEN);
    gapm_start_activity(link->conn_id, sizeof(struct gapm_init_param), &init_param);
    port_msg_evt_get_with_check_and_clear_goto(
        PORT_MSG_EVT_BLE_GAP_CONN_START, 10, _TAG_ERR, _TAG_ERR);

    link->addr = *addr;
    return XF_OK;

_TAG_ERR:;
    port_ble_link_free(link);
    return XF_ERR_INVALID_CHECK;
}

/**
 * @brief BLE GAP 断开连接
 *
 * @param addr 要断连的地址，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_disconnect(const xf_ble_addr_t *addr)
{
    port_ble_link_info_t *link = port_ble_link_get_by_addr(addr);
    XF_CHECK(link == NULL, XF_ERR_INVALID_ARG,
        TAG, "invalid addr");
    msg_info_list_index_t index_get = MSG_INFO_LIST_INDEX_INVALID;
    port_msg_param_var_t *param_get = NULL;
    gapc_disconnect(link->conn_id);
    port_msg_evt_get_with_check(index_get, PORT_MSG_EVT_BLE_GAP_DISCONNECT, &param_get, 100);
    port_msg_evt_clear_with_assert(index_get);
    port_ble_link_free(link);
    return XF_OK;
}

/**
 * @brief BLE GAP 添加配对
 *
 * @param addr 要配对的设备的地址，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_add_pair(const xf_ble_addr_t *addr);

/**
 * @brief BLE GAP 删除配对
 *
 * @param addr 要删除配对的设备的地址，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_del_pair(const xf_ble_addr_t *addr);

/**
 * @brief BLE GAP 删除所有配对
 *
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_del_pair_all(void);

/**
 * @brief BLE GAP 获取已配对的设备
 *
 * @param max_num 要获取的最大数量
 * @param[out] dev_list 获取到的设备列表，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_get_pair_list(
    uint16_t *max_num, xf_ble_addr_t *dev_list);

/**
 * @brief BLE GAP 获取已绑定的设备
 *
 * @param max_num 要获取的最大数量
 * @param[out] dev_list 获取到的设备列表，见 @ref xf_ble_addr_t
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_get_bond_list(
    int *max_num, xf_ble_addr_t *dev_list);

static struct gapc_pairing s_pair_params = {
    .auth = DEFAULT_PORT_PAIR_RESP_AUTHRN_RQMT_FLAG,
    .iocap = DEFAULT_PORT_PAIR_RESP_IOCAP_FLAG,
    .oob = DEFAULT_PORT_PAIR_RESP_OOB_FLAG,
    .sec_req = DEFAULT_PORT_PAIR_RESP_SECURITY_RQMT_FLAG,
    .ikey_dist = DEFAULT_PORT_PAIR_RESP_INITIATOR_KEY_DISTRIBUTION_FLAG,
    .rkey_dist = DEFAULT_PORT_PAIR_RESP_RESPONDER_KEY_DISTRIBUTION_FLAG,
    .key_size = DEFAULT_PORT_PAIR_ENC_KEY_SIZE_FLAG,
};

/**
 * @brief BLE GAP 设置安全参数
 *
 * @warning 当前该接口有部分问题未确定，禁止调用
 * @param conn_id 链接(连接) ID
 * @param param_type 安全参数类型，见 @ref xf_ble_sm_param_type_t
 * @param value 安全参数的数据值
 * @param len  安全参数的数据长度
 * @return xf_err_t
 *      - XF_OK                 成功
 *      - XF_FAIL               失败
 *      - (OTHER)               @ref xf_err_t
 */
xf_err_t xf_ble_gap_set_security_param(
    uint8_t conn_id, xf_ble_sm_param_type_t param_type, uint8_t len, uint8_t *value)
{
    xf_ble_sm_param_val_t *param_val = (xf_ble_sm_param_val_t *)value;
    /*因为没有对接的获取函数，且多类参数只有一个 api ，所以需要缓存着 */
    switch (param_type)
    {
    case XF_BLE_SM_PARAM_AUTHEN_RQMT:
    {
        /* 此处两边都是按标准的进行定义，所以直接设置 */
        s_pair_params.auth = param_val->authen_rqmt;
    }
    break;
    case XF_BLE_SM_PARAM_IO_CAP_MODE:
    {
        /* 此处两边都是按标准的进行定义，所以直接设置 */
        s_pair_params.iocap = param_val->io_capability;
    }
    break;
    case XF_BLE_SM_PARAM_OOB_DATA_FLAG:
    {
        /* 此处两边都是按标准的进行定义，所以直接设置 */
        s_pair_params.oob = param_val->oob_flag;
    }
    break;
    case XF_BLE_SM_PARAM_SECURITY_RQMT:
    {
        s_pair_params.sec_req = s_map_security_rqmt_to_gap_sec_req[param_val->security_rqmt];
    }
    break;
    default:
        break;
    }
    return XF_OK;
}

// GAP 回调注册
xf_err_t xf_ble_gap_event_cb_register(
    xf_ble_gap_evt_cb_t evt_cb,
    xf_ble_gap_evt_t events)
{
    UNUSED(events);
    s_ble_gap_evt_cb = evt_cb;
    return XF_OK;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_connect_req(uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_connection_req_ind *msg_param = &param->gapc_connection_req_ind;

    XF_LOGD(TAG,"msg_param:conn_id:%d,conn_hdl:%d,addr_type:%d", 
        conn_id, msg_param->conhdl, msg_param->peer_addr_type);
    xf_ble_gap_evt_cb_param_t evt_param =
    {
        .connect = 
        {
            .conn_id = conn_id,
            .link_role = (xf_ble_gap_link_role_type_t) msg_param->role,
            .peer_addr.type = (xf_ble_addr_type_t) msg_param->peer_addr_type,
        }
    };
    memcpy(evt_param.connect.peer_addr.addr, (const void *)msg_param->peer_addr.addr, XF_BLE_ADDR_LEN);
    
    s_ble_gap_evt_cb(XF_BLE_GAP_EVT_CONNECT_REQ, &evt_param);

    // gapc_connect_rsp(conn_id, GAP_AUTH_REQ_NO_MITM_NO_BOND);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_connect(uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_connection_ind *msg_param = &param->gapc_connection_ind;
    
    XF_LOGD(TAG, "[EARLY]CONN_IND:conn_id:%d,param->connhdl:%d", conn_id, msg_param->conhdl);
    // conn_id = msg_param->conhdl;    // 此处刚连接时 conn_id 是无效的，连接的 id 是在参数中

    xf_ble_gap_evt_cb_param_t evt_param =
    {
        .connect = 
        {
            .conn_id = conn_id,
            .link_role = (xf_ble_gap_link_role_type_t) msg_param->role,
            // .peer_addr.type = (xf_ble_addr_type_t) msg_param->peer_addr_type,
        }
    };

    // memcpy(evt_param.connect.peer_addr.addr, (const void *)msg_param->peer_addr.addr, XF_BLE_ADDR_LEN);
    /* FIXME 此处直接将 conn_id 等同 app_id 使用 */
    port_ble_app_t *app = port_gatt_app_get_by_conn_id(conn_id);
    XF_CHECK(app == NULL, PORT_MSG_EARLY_HANDLER_STATUS_CMPLT, TAG, "app get by conn_id(%d) failed", conn_id);
    app->conn_id = conn_id;
    
    s_ble_gap_evt_cb(XF_BLE_GAP_EVT_CONNECT, &evt_param);

    gapc_connect_rsp(conn_id, s_pair_params.auth);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

static void _app_ltk_gen(struct gapc_ltk *ltk)
{
    // Generate all the values
    ltk->key_size = GAP_KEY_LEN;
    ltk->ext_info = 0;
    
    ltk->ediv = rand_hword();
    
    for (int i = 0; i < GAP_RAND_NB_LEN; i++)
    {
        ltk->ltk.key[i]     = (uint8_t)rand_word();
        ltk->ltk.key[i + 8] = (uint8_t)rand_word();
        ltk->randnb.nb[i]   = (uint8_t)rand_word();
    }
}

port_msg_early_handler_status_t port_msg_early_handler_gap_pair_req(uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_bond_req_ind *msg_param = &param->gapc_bond_req_ind;

    XF_LOGD(TAG, "[EARLY]:PAIR REQ:%d", msg_param->request);
    switch (msg_param->request)
    {
        case (GAPC_PAIRING_REQ):
        {
            gapc_smp_pairing_rsp(conn_id, &s_pair_params);
        } break;
        case (GAPC_LTK_EXCH):
        {
            struct gapc_ltk ltk;
            _app_ltk_gen(&ltk);
            gapc_smp_pairing_ltk_exch(conn_id, &ltk);
        } break;
        case (GAPC_TK_EXCH):
        {
            XF_LOGD(TAG, "TK_EXCH(type:%d)", msg_param->data.tk_type);

            if (msg_param->data.tk_type == GAP_TK_OOB)
            {
                XF_LOGD(TAG, "TK_OOB >>>");
                return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
            }
            else if (msg_param->data.tk_type == GAP_TK_DISPLAY)
            {
                struct gap_sec_key tk;
                // Generate a PIN Code- (Between 100000 and 999999)
                uint32_t pin_code = (100000 + (rand_word() % 900000));
                // Set the TK value
                memset(&tk.key, 0, GAP_KEY_LEN);
                write32p(&tk.key, pin_code);

                XF_LOGD(TAG, "TK_DISPLAY:%06d", pin_code);
                gapc_smp_pairing_tk_exch(conn_id, true, &tk);
            }
            else
            {
                XF_LOGD(TAG, "TK_KEY_ENTRY:%d >>> nc num:%d", 
                    msg_param->data.tk_type, read32p(msg_param->data.nc_data.value));
                return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
            }
        } break;

        case (GAPC_CSRK_EXCH):
        {
            struct gap_sec_key csrk;
            XF_LOGD(TAG, "CSRK_EXCH");
            memset(&csrk.key, 0, GAP_KEY_LEN);
            gapc_smp_pairing_csrk_exch(conn_id, &csrk);
        } break;

        // #if (SEC_CON_ENB)
        // case (GAPC_OOB_EXCH):
        // {
        //     DEBUG("OOB_EXCH(conf,rand)>>>");
        //     debugHex(param->data.oob_data.conf, GAP_KEY_LEN);
        //     debugHex(param->data.oob_data.rand, GAP_KEY_LEN);

        //     return;
        // } //break;

        // case (GAPC_NC_EXCH):
        // {
        //     DEBUG("NC_EXCH(%06d)", read32p(param->data.nc_data.value));
        //     gapc_smp_pairing_nc_exch(conidx, true);
        // } break;
        // #endif //(SEC_CON_ENB)

        default:
        {
            XF_LOGW(TAG, "pair request has not been processed:%d", msg_param->request);
        } break;
    }
    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_pair_result(uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_bond_ind *msg_param = &param->gapc_bond_ind;

    XF_LOGD(TAG, "[EARLY]:PAIR Result:%d", msg_param->info);

    switch (msg_param->info)
    {
        case (GAPC_PAIRING_SUCCEED):
        {
            XF_LOGD(TAG, "pair success(auth:%X,ltk:%d)",
                msg_param->data.auth.info, msg_param->data.auth.ltk_present);
            /* TODO 此处可以做 ltk 的保存 */
        } break;

        case (GAPC_PAIRING_FAILED):
        {
            XF_LOGD(TAG, "pair failed(reason:0x%X)", msg_param->data.reason);
        } break;

        case (GAPC_REPEATED_ATTEMPT):
        {
            XF_LOGW(TAG, "pair request issue, Repeated attempt");
            gapc_disconnect(conn_id);
        } break;

        case (GAPC_IRK_EXCH):
        {
            XF_LOGD(TAG, "IRK_EXCH(irk,addr)");
#if XF_LOG_LEVEL >= XF_LOG_DEBUG
            XF_LOG_BUFFER_HEX((void *)msg_param->data.irk.irk.key, GAP_KEY_LEN);
            XF_LOG_BUFFER_HEX((void *)msg_param->data.irk.addr.addr.addr, GAP_BD_ADDR_LEN);
            xf_log_printf("\r\n");
#endif
            // Store peer identity
        } break;

        // In Secure Connections we get BOND_IND with SMPC calculated LTK
        case (GAPC_LTK_EXCH) :
        {
            XF_LOGD(TAG, "Bond LTK_EXCH(size:%d)", msg_param->data.ltk.key_size);
#if XF_LOG_LEVEL >= XF_LOG_DEBUG
            XF_LOG_BUFFER_HEX((void *)msg_param->data.ltk.ltk.key, sizeof(struct gapc_ltk));
            xf_log_printf("\r\n");
#endif
            // Store peer LTK
        } break;

        default:
        {
            XF_LOGW(TAG, "pair result has not been processed:%d", msg_param->info);
        } break;
    }
    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_disconnect(uint8_t conn_id, const port_msg_param_var_t *param)
{

    const struct gapc_disconnect_ind *msg_param = &param->gapc_disconnect_ind;

    XF_LOGD(TAG, "[EARLY]:disconnect:conn_hdl:%d,reason:%d",
        msg_param->conhdl, msg_param->reason);

    xf_ble_gap_evt_cb_param_t evt_param =
    {
        .disconnect = 
        {
            .conn_id = conn_id,
            .reason = (xf_ble_gap_disconnect_reason_t)msg_param->reason,
        }
    };
    
    s_ble_gap_evt_cb(XF_BLE_GAP_EVT_DISCONNECT, &evt_param);

    return PORT_MSG_EARLY_HANDLER_STATUS_RECORD;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_scan_result(uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapm_ext_adv_report_ind *msg_param = &param->gapm_ext_adv_report_ind;
    
    XF_LOGD(TAG, "[EARLY]:scan result");
    
    /* 扫描活动 ID 无效则直接返回（一般是在停止扫描处理的阶段） */
    if(s_scan_id == PORT_INVALID_SCAN_ID)
    {
        return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
    }

    /* FIXME 不同太确定哪个是否是扫描到的对端的地址 */
    xf_ble_gap_evt_cb_param_t evt_param =
    {
        .scan_result = 
        {
            .rssi = msg_param->rssi,
            .adv_data = (uint8_t *)msg_param->data,
            .adv_data_len = msg_param->length,
            .addr_scanned.type = (xf_ble_addr_type_t) msg_param->trans_addr.addr_type,
            // .type = msg_param
        }
    };

    memcpy(evt_param.scan_result.addr_scanned.addr, (const void *)msg_param->trans_addr.addr.addr, XF_BLE_ADDR_LEN);
    
    s_ble_gap_evt_cb(XF_BLE_GAP_EVT_SCAN_RESULT, &evt_param);

    struct gapc_conn_param _param = {
        .intv_min = 6,
        .intv_max = 6,
        .latency = 0,
        .time_out = 2000,
    };
    gapc_update_param(conn_id, &_param);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_conn_params_update_req(
    uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_param_update_req_ind *msg_param = &param->gapc_param_update_req_ind;

    XF_LOGD(TAG,"[EARLY]:CONN_PARAM_UPD REQ:conn_id:%d,inv_min:%d,inv_max:%d,latency:%d,timeout:%d",
        conn_id, msg_param->intv_min, msg_param->intv_max, msg_param->latency, msg_param->time_out);

    gapc_param_update_rsp(conn_id, true, msg_param->intv_min, msg_param->intv_max);

    XF_LOGD(TAG,"[EARLY]:CONN_PARAM_UPD: rsp cmplt,it will upd local conn_param");
    struct gapc_conn_param param_cfg =
    {
        .intv_max = msg_param->intv_max,
        .intv_min = msg_param->intv_min,
        .latency = msg_param->latency,
        .time_out = msg_param->time_out,
    };
    gapc_update_param(conn_id, &param_cfg);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_conn_params_update_ind(
    uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_param_updated_ind *msg_param = &param->gapc_param_updated_ind;

    XF_LOGD(TAG,"[EARLY]:CONN_PARAM_UPD IND:conn_id:%d,interval:%d,latency:%d,timeout:%d",
        conn_id, msg_param->con_interval, msg_param->con_latency, msg_param->sup_to);

    xf_ble_gap_evt_cb_param_t evt_param =
    {
        .conn_param_upd = 
        {
            .conn_id = conn_id,
            .interval = msg_param->con_interval,
            .latency = msg_param->con_latency,
            .timeout = msg_param->sup_to,
        }
    };
    
    s_ble_gap_evt_cb(XF_BLE_GAP_EVT_CONN_PARAMS_UPDATE, &evt_param);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

port_msg_early_handler_status_t port_msg_early_handler_gap_cmplt_evt(
    uint8_t conn_id, const port_msg_param_var_t *param)
{
    const struct gapc_cmp_evt *msg_param = &param->gapc_cmp_evt;
    enum gapc_operation operation = (enum gapc_operation)msg_param->operation;
    UNUSED(operation);
    XF_LOGD(TAG,"[EARLY]:CMPLT:conn_id:%d,opt:%d,status:%d",
        conn_id, operation, msg_param->status);

    return PORT_MSG_EARLY_HANDLER_STATUS_CMPLT;
}

/* ==================== [Static Functions] ================================== */

/**
 * @brief 仅用于默认的事件回调函数
 *  这样可以不再在各调用处检查 s_ble_gap_evt_cb 的有效性
 */
xf_err_t _default_ble_gap_evt_cb(
    xf_ble_gap_evt_t event,
    xf_ble_gap_evt_cb_param_t *param)
{
    return XF_OK;
}

#endif
